home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Eagles Nest BBS 4
/
Eagles_Nest_Mac_Collection_Disc_4.TOAST
/
Database Management
/
FoxPro25#1
/
FoxPro 2.5 Disk - 1 Setup.image
/
Genxtab.prg
/
Genxtab.bin
Wrap
Text File
|
1993-12-04
|
35KB
|
1,125 lines
*:*********************************************************************
*:
*: Procedure file: C:\FOXPRO2\GENXTAB\GENXTAB.PRG
*:
*: System: GENXTAB
*: Author: Microsoft Corp.
*: Copyright (c) 1993, Microsoft Corp.
*: Last modified: 1/4/93 10:17
*:
*: Procs & Fncts: APPERROR
*: : ESC_PROC
*: : JUSTFNAME()
*: : JUSTSTEM()
*: : BAILOUT
*: : DEFAULTEXT()
*: : ALERT
*: : ACTTHERM
*: : UPDTHERM
*: : MAPNAME()
*: : DEACTTHERMO
*: : FORCEEXT
*: : JUSTPATH
*: : ADDBS
*: : MAKESTRG
*:
*: Calls: APPERROR (procedure in GENXTAB.PRG)
*: : ESC_PROC (procedure in GENXTAB.PRG)
*: : JUSTFNAME() (function in GENXTAB.PRG)
*: : JUSTSTEM() (function in GENXTAB.PRG)
*: : BAILOUT (procedure in GENXTAB.PRG)
*: : DEFAULTEXT() (function in GENXTAB.PRG)
*: : ALERT (procedure in GENXTAB.PRG)
*: : ACTTHERM (procedure in GENXTAB.PRG)
*: : UPDTHERM (procedure in GENXTAB.PRG)
*: : MAPNAME() (function in GENXTAB.PRG)
*: : DEACTTHERMO (procedure in GENXTAB.PRG)
*:
*: Uses: XTABTEMP.DBF
*:
*:*********************************************************************
***********************************************************************
*
* Notes: This program is intended to be called by RQBE or a program
* generated by RQBE. On entry, a table should be open in the
* current work area, and it should contain at most one record
* for each cell in a cross-tabulation. This table *must* be in
* row order, or you will receive an "unexpected end of file"
* error when you run GENXTAB.
*
* The rowfld field in each record becomes the y-axis (rows) for
* a cross-tab and the colfld field becomes the x-axis (columns)
* The actual cross-tab results are saved to the database name
* specified by "outfname."
*
* The basic strategy goes like this. Produce an empty database
* with one field/column for each unique value of input field
* colfld, plus one additional field for input field rowfld values.
* This process determines the column headings in the database.
* Next fill in the rows, but only for the first field in the output
* database--the one that contains values for input field rowfld.
* At this point, we have column headings "across the top"
* and row identifiers "down the side." Finally, look up
* the cell values for the row/column intersections and put
* them into the output database.
*
*
* Calling example:
* DO genxtab WITH 'XTAB.DBF',.T.,.T.,.T.,1,2,5,.T.
*
* This command causes GENXTAB to write the output database to
* 'XTAB.DBF'. However, XTAB.DBF will be deleted and the output
* stored to a cursor called XTAB. The input database will be closed
* at the conclusion of the program. The rows in XTAB.DBF will
* contain the unique values of field 1 in the database that is
* selected when GENXTAB is called, the columns will contain
* unique values of field 2 in the input database, and the
* cell values will come from field 5 in the input database.
* The thermometer will be shown. A total field will be created.
*
***********************************************************************
PARAMETERS outfname, ;
cursonly, ;
closeinput, ;
showtherm, ;
rowfld, ;
colfld, ;
cellfld, ;
xfoot
PRIVATE ALL
m.g_dlgface = IIF(_MAC,"Geneva","MS Sans Serif")
m.g_dlgsize = IIF(_MAC,10,8.000)
m.g_dlgstyle = IIF(_MAC,"","B")
EXTERNAL ARRAY coluniq
EXTERNAL ARRAY colcnt
* -------------------------------------------------------------------------
* Do opening housekeeping
* -------------------------------------------------------------------------
IF SET("TALK") = "ON"
SET TALK OFF
xtalk_stat = "ON"
ELSE
xtalk_stat = "OFF"
ENDIF
xsafe_stat = SET("SAFETY")
SET SAFETY OFF
xesc_stat = SET("ESCAPE")
SET ESCAPE ON
#if "MAC" $ UPPER(VERSION(1))
IF _MAC
m.mmacdesk = SET("MACDESKTOP")
SET MACDESKTOP ON
ENDIF
#endif
in_esc = ON('ESCAPE')
in_err = ON('ERROR')
ON ERROR DO apperror WITH PROGRAM(),MESSAGE(),MESSAGE(1),LINENO(),ERROR()
ON ESCAPE DO esc_proc
* -------------------------------------------------------------------------
* Set default values for parameters
* -------------------------------------------------------------------------
IF PARAMETERS() < 1
m.outfname = 'XTAB.DBF'
ENDIF
IF PARAMETERS() < 2
* Default to creating the same kind of output as we got as input.
* If the input "database" is a cursor, make the output a cursor.
* If the input "database" is an actual database, make the output a table.
cname = justfname(DBF())
DO CASE
CASE EMPTY(cname) && create a table if nothing is currently selected
cursonly = .F.
CASE ISDIGIT(LEFT(cname,1))
cursonly = .T.
OTHERWISE
cursonly = .F.
ENDCASE
ENDIF
IF PARAMETERS() < 3
* Close the input database
closeinput = .T.
ENDIF
IF PARAMETERS() < 4
* show the thermometer
showtherm = .T.
ENDIF
IF PARAMETERS() < 5
* the field position in the input database for the crosstab rows
m.rowfld = 1
ENDIF
IF PARAMETERS() < 6
* the field position in the input database for the crosstab columns
m.colfld = 2
ENDIF
IF PARAMETERS() < 7
* the field position in the input database for the crosstab cells
m.cellfld = 3
ENDIF
IF PARAMETERS() < 8
* Create a total field?
m.xfoot = .F.
ENDIF
* Define characters that are not allowed in field names
m.badchars = 'ÅÇÉÑÖÜáàâäãåéèêëíìîïñóòôö†°¢£§• /\,-=:;{}[]!@#$%^&*.<>()'+;
'+|Äõúùûü¶ß®©™´¨≠ÆØ∞±≤≥¥µ∂∑∏π∫ªºΩæø¿¡¬√ƒ≈Δ«»… ÀÃÕŒœ'+;
'–—“”‘’÷◊ÿŸ⁄€‹›fifl‡·‚„‰ÂÊÁËÈÍÎÏÌÓÔÒÚÛÙıˆ˜¯˘˙˚¸˝˛'+CHR(39)
* Map European characters to these
m.stdascii = 'ueaaaaceeeiiAaEaAooouuyouaiounN'
IF !showtherm
m.recthresh = 100000000 && don't show the thermometer
ELSE
m.recthresh = 1 && show it if more than this many input records
ENDIF
m.g_thermwidth = 0 && Thermometer width
m.outfname = removequotes(m.outfname)
m.outstem = juststem(m.outfname)
* -------------------------------------------------------------------------
* Construct the output database structure
* -------------------------------------------------------------------------
m.dbfname = ALIAS()
m.dbfstem = Juststem(m.dbfname)
therm_on = (RECCOUNT() >= recthresh)
* Select one, if no database is open in the current workarea
m.ok = .F.
DO WHILE NOT ok
DO CASE
CASE EMPTY(m.dbfname)
m.dbfname = GETFILE('DBF','Please locate the input database')
m.dbfstem = juststem(m.dbfname)
IF EMPTY(m.dbfname)
* User canceled out of dialog, so quit the program
DO bailout WITH .T.
ENDIF
CASE FULLPATH(defaultext(m.dbfname,'DBF')) == ;
FULLPATH(defaultext(m.outfname,'DBF'))
SET CURSOR OFF
WAIT WINDOW "The input and output databases must be different."
SET CURSOR ON
m.dbfname = ''
OTHERWISE
IF USED(m.dbfstem)
SELECT (m.dbfstem)
ELSE
SELECT 0
USE (m.dbfname) ALIAS (m.dbfstem)
ENDIF
IF FCOUNT() < 3
DO alert WITH "Crosstab input databases require; at least three fields"
m.dbfname = ''
ELSE
ok = .T.
ENDIF
ENDCASE
ENDDO
IF RECCOUNT() = 0
DO alert WITH "Cannot prepare crosstab on empty database"
DO bailout WITH .T.
ENDIF
* Gather information on the currently selected database fields
DIMENSION inpfields[FCOUNT(),4]
m.numflds = AFIELDS(inpfields)
* Map the physical input database field to logical field positions
m.rowfldname = inpfields[m.rowfld,1]
m.colfldname = inpfields[m.colfld,1]
m.cellfldname = inpfields[m.cellfld,1]
* None of these fields are allowed to be memo fields
IF inpfields[1,2] $ 'MGP'
DO alert WITH "The crosstab row field in the input; database cannot be a memo, general or picture field."
DO bailout WITH .T.
ENDIF
IF inpfields[2,2] $ 'MGP'
DO alert WITH "The crosstab column field in the input; database cannot be a memo, general or picture field."
DO bailout WITH .T.
ENDIF
IF inpfields[3,2] $ 'MGP'
DO alert WITH "The crosstab cell field in the input; database cannot be a memo, general or picture field."
DO bailout WITH .T.
ENDIF
IF therm_on
DO acttherm WITH "Generating cross-tabulation ..."
DO updtherm WITH 5
ENDIF
* Set the mouse off to avoid flicker on some systems
SET MOUSE OFF
* Count the number of columns we need to create the cross tab.
* This step could be combined with the following one so that there
* would only be one SELECT operation performed. It is coded in this
* way to avoid running out of memory if there are an unexpectedly
* large number of unique values of field 2 in the input database.
SELECT COUNT(DISTINCT &colfldname) FROM (m.dbfname) INTO ARRAY colcnt
DO CASE
CASE colcnt[1] > 254
DO alert WITH "Too many unique values of "+PROPER(m.colfldname);
+ ".; The maximum is 254."
DO bailout WITH .T.
CASE colcnt[1] = 0
DO alert WITH "No columns found."
DO bailout WITH .T.
ENDCASE
* Get the number of decimal places in numeric fields
* and extract all the unique values of colfldname
IF inpfields[m.colfld,2] $ 'NF' && numeric or floating field
m.cdec = inpfields[m.colfld,4]
* Handle numbers separately to preserve correct sort order
SELECT DISTINCT &colfldname ;
FROM (m.dbfname) INTO ARRAY coluniq
FOR i = 1 TO ALEN(coluniq)
coluniq[i] = mapname(coluniq[i],m.cdec)
ENDFOR
ELSE && non-numeric field
m.cdec = 0
* Create an array to hold the output database fields.
SELECT DISTINCT mapname(&colfldname,m.cdec) ;
FROM (m.dbfname) INTO ARRAY coluniq
ENDIF
IF therm_on
DO updtherm WITH 15
ENDIF
* The field type, length and decimals in the output array control the
* cross-tab cells
IF !m.xfoot
DIMENSION outarray[ALEN(coluniq)+1,4]
ELSE
DIMENSION outarray[ALEN(coluniq)+2,4]
ENDIF
* Field 1 in the output DBF holds the unique values of the row input field.
* It is handled separately from the other fields, which take their names
* from input database colfld and their parameters (e.g., length) from
* input database cellfld.
outarray[1,1] = mapname(inpfields[1,1])
outarray[1,2] = inpfields[1,2]
outarray[1,3] = inpfields[1,3]
outarray[1,4] = inpfields[1,4]
FOR i = 2 TO ALEN(coluniq) + 1
outarray[i,1] = mapname(coluniq[i-1],m.cdec)
outarray[i,2] = inpfields[3,2] && field type
outarray[i,3] = inpfields[3,3] && field length
outarray[i,4] = inpfields[3,4] && decimals
ENDFOR
* Create a field for the cross-footing, if that option was selected
IF m.xfoot
outarray[ALEN(coluniq)+2,1] = 'XTOTALS'
outarray[ALEN(coluniq)+2,2] = inpfields[3,2]
outarray[ALEN(coluniq)+2,3] = inpfields[3,3]
outarray[ALEN(coluniq)+2,4] = inpfields[3,4]
ENDIF
* Make sure that the output file is not already in use somewhere
IF USED(m.outstem)
SELECT (m.outstem)
USE
ENDIF
IF !cursonly
CREATE TABLE (outfname) FROM ARRAY outarray
ELSE
CREATE CURSOR (outfname) FROM ARRAY outarray
ENDIF
IF therm_on
DO updtherm WITH 25
ENDIF
* Get rid of the temporary arrays
RELEASE outarray, coluniq, inpfields
* -------------------------------------------------------------------------
* Add output database rows and replace the first field
* -------------------------------------------------------------------------
* Select distinct rows into a table (instead of an array) so that
* there can be lots of rows. If we select into an array, we may
* run out of RAM if there are many rows.
SELECT DISTINCT &rowfldname FROM (m.dbfname) INTO TABLE xtabtemp
IF therm_on
DO updtherm WITH 30
ENDIF
SELECT (m.outstem)
APPEND FIELD (FIELD(1)) FROM xtabtemp
IF therm_on
DO updtherm WITH 35
ENDIF
* -------------------------------------------------------------------------
* Look up and replace the cell values
* -------------------------------------------------------------------------
*
* This algorithm makes one pass through the input file, dropping its
* values into the output file. It exploits the fact that the output
* file is known to be in row order.
*
* Start at the top of the output file
SELECT (m.outstem)
GOTO TOP
outf1name = FIELD(1)
* Start at the top of the input file
SELECT (m.dbfstem)
GOTO TOP
SCAN
m.f1 = EVAL(m.rowfldname) && get next row value from input
m.f2 = mapname(EVAL(m.colfldname),m.cdec) && get corresponding column value
m.f3 = EVAL(m.cellfldname) && get cell value
* Find the right row in the output file
SELECT (m.outstem)
DO WHILE !(EVAL(outf1name) == m.f1) AND !EOF()
SKIP
ENDDO
IF !EOF()
IF TYPE(m.f2) $ "NF"
REPLACE (m.f2) WITH &f2 + m.f3
ELSE
REPLACE (m.f2) WITH m.f3
ENDIF
ELSE
DO alert WITH "Unexpected end of output file.;" ;
+ "The input file may be out of sequence."
DO bailout WITH .T.
ENDIF
SELECT (m.dbfstem)
* Map thermometer to remaining portion of display
IF therm_on
DO CASE
CASE RECCOUNT() > 1000
IF RECNO() % 100 = 0
DO updtherm WITH INT(RECNO() / RECCOUNT() * 65)+ 35
ENDIF
OTHERWISE
IF RECNO() % 10 = 0
DO updtherm WITH INT(RECNO() / RECCOUNT() * 65)+ 35
ENDIF
ENDCASE
ENDIF
ENDSCAN
* Cross-foot the columns and put the results into the total field
IF m.xfoot
SELECT (m.outstem)
m.totfldname = FIELD(FCOUNT())
SCAN
* Sum the relevant fields
m.gtotal = 0
FOR i = 2 TO FCOUNT() - 1
m.gtotal = m.gtotal + EVAL(FIELD(i))
ENDFOR
REPLACE (m.totfldname) WITH m.gtotal
ENDSCAN
ENDIF
IF therm_on
DO updtherm WITH 100
DO deactthermo
ENDIF
IF USED("XTABTEMP")
SELECT xtabtemp
USE
ENDIF
IF FILE("xtabtemp.dbf")
DELETE FILE xtabtemp.dbf
ENDIF
* Close the input database
IF closeinput
SELECT (m.dbfstem)
USE
ENDIF
* Leave the output database/cursor selected
SELECT (m.outstem)
GOTO TOP
* Do closing housekeeping
DO bailout WITH .F.
RETURN
*!*********************************************************************
*!
*! Function: MAPNAME()
*!
*! Called by: GENXTAB.PRG
*!
*! Calls: ALERT (procedure in GENXTAB.PRG)
*! : BAILOUT (procedure in GENXTAB.PRG)
*!
*!*********************************************************************
FUNCTION mapname
* Translate a field value of any type into a string containing a valid
* field name.
PARAMETER in_name, in_dec
IF PARAMETERS() = 1
in_dec = 0
ENDIF
DO CASE
CASE TYPE("in_name") $ 'CM'
DO CASE
CASE EMPTY(m.in_name)
m.retval = 'C_BLANK'
OTHERWISE
m.retval = SUBSTR(CHRTRAN(m.in_name,m.badchars,m.stdascii),1,10)
IF !ISALPHA(LEFT(m.retval,1))
m.retval = 'C_'+LEFT(m.retval,8)
ENDIF
ENDCASE
CASE TYPE("in_name") $ 'NF'
m.retval = 'N_'+ALLTRIM(CHRTRAN(STR(m.in_name,8,in_dec),'.',''))
CASE TYPE("in_name") = 'D'
DO CASE
CASE EMPTY(m.in_name)
m.retval = 'D_BLANK'
OTHERWISE
m.retval = 'D_' + CHRTRAN(DTOS(m.in_name),m.badchars,m.stdascii)
ENDCASE
CASE TYPE("in_name") = 'L'
IF m.in_name = .T.
m.retval = 'T'
ELSE
m.retval = 'F'
ENDIF
CASE TYPE("in_name") = 'P'
DO alert WITH "Picture type fields are not allowed here."
DO bailout WITH .T.
OTHERWISE
DO alert WITH "Unknown field type."
DO bailout WITH .T.
ENDCASE
m.retval = PADR(UPPER(ALLTRIM(m.retval)),10)
RETURN m.retval
*!*********************************************************************
*!
*! Function: JUSTSTEM()
*!
*! Called by: GENXTAB.PRG
*!
*!*********************************************************************
FUNCTION juststem
* Return just the stem name from "filname"
PARAMETERS filname
PRIVATE ALL
IF RAT('\',m.filname) > 0
m.filname = SUBSTR(m.filname,RAT('\',m.filname)+1,255)
ENDIF
IF RAT(':',m.filname) > 0
m.filname = SUBSTR(m.filname,RAT(':',m.filname)+1,255)
ENDIF
IF RAT('.',m.filname) > 0
m.filname = SUBSTR(m.filname,1,RAT('.',m.filname)-1)
ENDIF
RETURN ALLTRIM(UPPER(m.filname))
*!*********************************************************************
*!
*! Procedure: FORCEEXT
*!
*! Calls: JUSTPATH (procedure in GENXTAB.PRG)
*! : JUSTFNAME() (function in GENXTAB.PRG)
*! : ADDBS (procedure in GENXTAB.PRG)
*!
*!*********************************************************************
FUNCTION forceext
* Force the extension of "filname" to be whatever ext is.
PARAMETERS filname,ext
PRIVATE ALL
IF SUBSTR(m.ext,1,1) = "."
m.ext = SUBSTR(m.ext,2,3)
ENDIF
m.pname = justpath(m.filname)
m.filname = justfname(UPPER(ALLTRIM(m.filname)))
IF RAT('.',m.filname) > 0
m.filname = SUBSTR(m.filname,1,RAT('.',m.filname)-1) + '.' + m.ext
ELSE
m.filname = m.filname + '.' + m.ext
ENDIF
RETURN addbs(m.pname) + m.filname
*!*********************************************************************
*!
*! Function: DEFAULTEXT()
*!
*! Called by: GENXTAB.PRG
*!
*! Calls: JUSTPATH (procedure in GENXTAB.PRG)
*! : JUSTFNAME() (function in GENXTAB.PRG)
*! : ADDBS (procedure in GENXTAB.PRG)
*!
*!*********************************************************************
FUNCTION defaultext
* Add a default extension to "filname" if it doesn't have one already
PARAMETERS filname,ext
PRIVATE ALL
IF SUBSTR(ext,1,1) = "."
m.ext = SUBSTR(m.ext,2,3)
ENDIF
m.pname = justpath(m.filname)
m.filname = justfname(UPPER(ALLTRIM(m.filname)))
IF !EMPTY(m.filname) AND AT('.',m.filname) = 0
m.filname = m.filname + '.' + m.ext
RETURN addbs(m.pname) + m.filname
ELSE
RETURN filname
ENDIF
*!*********************************************************************
*!
*! Function: JUSTFNAME()
*!
*! Called by: GENXTAB.PRG
*! : DEFAULTEXT() (function in GENXTAB.PRG)
*! : FORCEEXT (procedure in GENXTAB.PRG)
*!
*!*********************************************************************
FUNCTION justfname
* Return just the filename (i.e., no path) from "filname"
PARAMETERS filname
PRIVATE ALL
IF RAT('\',m.filname) > 0
m.filname = SUBSTR(m.filname,RAT('\',m.filname)+1,255)
ENDIF
IF RAT(':',m.filname) > 0
m.filname = SUBSTR(m.filname,RAT(':',m.filname)+1,255)
ENDIF
RETURN ALLTRIM(UPPER(m.filname))
*!*********************************************************************
*!
*! Procedure: JUSTPATH
*!
*! Called by: DEFAULTEXT() (function in GENXTAB.PRG)
*! : FORCEEXT (procedure in GENXTAB.PRG)
*!
*!*********************************************************************
FUNCTION justpath
* Return just the path name from "filname"
PARAMETERS m.filname
PRIVATE ALL
m.filname = ALLTRIM(UPPER(m.filname))
m.pathsep = IIF(_MAC,":", "\")
IF _MAC
m.found_it = .F.
m.maxchar = max(RAT("\", m.filname), RAT(":", m.filname))
IF m.maxchar > 0
m.filname = SUBSTR(m.filname,1,m.maxchar)
IF RIGHT(m.filname,1) $ ":\" AND LEN(m.filname) > 1 ;
AND !(SUBSTR(m.filname,LEN(m.filname)-1,1) $ ":\")
m.filname = SUBSTR(m.filname,1,LEN(m.filname)-1)
ENDIF
RETURN m.filname
ENDIF
ELSE
IF m.pathsep $ filname
m.filname = SUBSTR(m.filname,1,RAT(m.pathsep,m.filname))
IF RIGHT(m.filname,1) = m.pathsep AND LEN(m.filname) > 1 ;
AND SUBSTR(m.filname,LEN(m.filname)-1,1) <> m.pathsep
m.filname = SUBSTR(m.filname,1,LEN(m.filname)-1)
ENDIF
RETURN m.filname
ENDIF
ENDIF
RETURN ''
*!*********************************************************************
*!
*! Procedure: ADDBS
*!
*! Called by: DEFAULTEXT() (function in GENXTAB.PRG)
*! : FORCEEXT (procedure in GENXTAB.PRG)
*!
*!*********************************************************************
FUNCTION addbs
* Add a backslash to a path name, if there isn't already one there
PARAMETER pathname
PRIVATE ALL
m.pathname = ALLTRIM(UPPER(m.pathname))
IF !(RIGHT(m.pathname,1) $ '\:') AND !EMPTY(m.pathname)
m.pathname = m.pathname + IIF(_MAC,":",'\')
ENDIF
RETURN m.pathname
*!*********************************************************************
*!
*! Procedure: APPERROR
*!
*! Called by: GENXTAB.PRG
*!
*! Calls: ALERT (procedure in GENXTAB.PRG)
*! : BAILOUT (procedure in GENXTAB.PRG)
*!
*!*********************************************************************
PROCEDURE apperror
* Simple ON ERROR routine
PARAMETERS e_program,e_message,e_source,e_lineno,e_error
ON ERROR
SET MOUSE ON
m.e_source = ALLTRIM(m.e_source)
DO alert WITH 'Line No.: '+ALLTRIM(STR(m.e_lineno,5))+';' ;
+'Program: '+m.e_program +';' ;
+' Error: '+m.e_message +';' ;
+' Source: '+IIF(LEN(m.e_source)<50,;
m.e_source,SUBSTR(m.e_source,1,50)+'...')
DO bailout WITH .T.
*!*********************************************************************
*!
*! Procedure: ALERT
*!
*! Called by: GENXTAB.PRG
*! : APPERROR (procedure in GENXTAB.PRG)
*! : MAPNAME() (function in GENXTAB.PRG)
*!
*!*********************************************************************
PROCEDURE alert
* Display an error message, automatically sizing the message window
* as necessary. Semicolons in "strg" mean "new line".
PARAMETERS strg
PRIVATE ALL
SET MOUSE ON
in_talk = SET('TALK')
SET TALK OFF
in_cons = SET('CONSOLE')
m.numlines = OCCURS(';',m.strg) + 1
DIMENSION alert_arry[m.numlines]
m.remain = m.strg
m.maxlen = 0
FOR i = 1 TO m.numlines
IF AT(';',m.remain) > 0
alert_arry[i] = SUBSTR(m.remain,1,AT(';',m.remain)-1)
alert_arry[i] = CHRTRAN(alert_arry[i],';','')
m.remain = SUBSTR(m.remain,AT(';',m.remain)+1)
ELSE
alert_arry[i] = m.remain
m.remain = ''
ENDIF
IF LEN(alert_arry[i]) > SCOLS() - 6
alert_arry[i] = SUBSTR(alert_arry[i],1,SCOLS()-6)
ENDIF
IF LEN(alert_arry[i]) > m.maxlen
m.maxlen = LEN(alert_arry[i])
ENDIF
ENDFOR
m.top_row = INT( (SROWS() - 4 - m.numlines) / 2)
m.bot_row = m.top_row + 3 + m.numlines
m.top_col = INT((SCOLS() - m.maxlen - 6) / 2)
m.bot_col = m.top_col + m.maxlen + 6
IF _MAC
DEFINE WINDOW alert FROM m.top_row,m.top_col TO m.bot_row,m.bot_col;
DOUBLE COLOR SCHEME 7
ELSE
DEFINE WINDOW alert FROM m.top_row,m.top_col TO m.bot_row,m.bot_col;
DOUBLE COLOR SCHEME 7
ENDIF
ACTIVATE WINDOW alert
FOR i = 1 TO m.numlines
@ i,3 SAY PADC(alert_arry[i],m.maxlen)
ENDFOR
SET CONSOLE OFF
keycode = INKEY(0,'HM')
SET CONSOLE ON
RELEASE WINDOW alert
IF m.in_talk = "ON"
SET TALK ON
ENDIF
IF m.in_cons = "OFF"
SET CONSOLE OFF
ENDIF
RETURN
*!*********************************************************************
*!
*! Procedure: MAKESTRG
*!
*!*********************************************************************
FUNCTION makestrg
PARAMETER in_val
DO CASE
CASE TYPE("in_val") = "C"
RETURN in_val
CASE TYPE("in_val") $ "NF"
RETURN ALLTRIM(STR(in_val))
CASE TYPE("in_val") = "D"
RETURN DTOC(in_val)
CASE TYPE("in_val") = "L"
IF in_val
RETURN ".T."
ELSE
RETURN ".F."
ENDIF
OTHERWISE
RETURN in_val
ENDCASE
*!*********************************************************************
*!
*! Procedure: ESC_PROC
*!
*! Called by: GENXTAB.PRG
*!
*! Calls: BAILOUT (procedure in GENXTAB.PRG)
*!
*!*********************************************************************
PROCEDURE esc_proc
WAIT WINDOW "Cross tabulation terminated." TIMEOUT 1
CLEAR TYPEAHEAD
DO bailout
*!*********************************************************************
*!
*! Procedure: BAILOUT
*!
*! Called by: GENXTAB.PRG
*! : APPERROR (procedure in GENXTAB.PRG)
*! : ESC_PROC (procedure in GENXTAB.PRG)
*! : MAPNAME() (function in GENXTAB.PRG)
*!
*! Uses: XTABTEMP.DBF
*!
*!*********************************************************************
PROCEDURE bailout
PARAMETER docancl
PRIVATE docancl
DO CASE
CASE PARAMETERS() = 0
m.docancl = .T.
ENDCASE
IF WONTOP('THERMOMETE')
RELEASE WINDOW thermomete
ENDIF
IF USED("XTABTEMP")
SELECT xtabtemp
USE
ENDIF
IF FILE("xtabtemp.dbf")
DELETE FILE xtabtemp.dbf
ENDIF
IF m.xsafe_stat = "ON"
SET SAFETY ON
ENDIF
IF m.xesc_stat = "ON"
SET ESCAPE ON
ELSE
SET ESCAPE OFF
ENDIF
IF m.xtalk_stat = "ON"
SET TALK ON
ENDIF
#if "MAC" $ UPPER(VERSION(1))
IF _MAC
SET MACDESKTOP &mmacdesk
ENDIF
#endif
ON ERROR &in_err
ON ESCAPE &in_esc
SET MOUSE ON
IF m.docancl
m.outfname = ''
CANCEL
ENDIF
*
* ACTTHERM(<text>) - Activate thermometer.
*
* Activates thermometer. Update the thermometer with UPDTHERM().
* Thermometer window is named "thermometer." Be sure to RELEASE
* this window when done with thermometer. Creates the global
* m.g_thermwidth.
*
*!*****************************************************************************
*!
*! Procedure: ACTTHERM
*!
*!*****************************************************************************
PROCEDURE acttherm
PARAMETER m.prompt
PRIVATE m.text
m.text = ""
IF _MAC OR _WINDOWS
IF TXTWIDTH(m.prompt, m.g_dlgface, m.g_dlgsize, m.g_dlgstyle) > 43
DO WHILE TXTWIDTH(m.prompt+"...", m.g_dlgface, m.g_dlgsize, m.g_dlgstyle) > 43
m.prompt = LEFT(m.prompt, LEN(m.prompt)-1)
ENDDO
m.prompt = m.prompt + "..."
ENDIF
DO CASE
CASE _WINDOWS
DEFINE WINDOW thermomete ;
AT INT((SROW() - (( 5.615 * ;
FONTMETRIC(1, m.g_dlgface, m.g_dlgsize, m.g_dlgstyle )) / ;
FONTMETRIC(1, WFONT(1,""), WFONT( 2,""), WFONT(3,"")))) / 2), ;
INT((SCOL() - (( 63.833 * ;
FONTMETRIC(6, m.g_dlgface, m.g_dlgsize, m.g_dlgstyle )) / ;
FONTMETRIC(6, WFONT(1,""), WFONT( 2,""), WFONT(3,"")))) / 2) ;
SIZE 5.615,63.833 ;
FONT m.g_dlgface, m.g_dlgsize ;
STYLE m.g_dlgstyle ;
NOFLOAT ;
NOCLOSE ;
NONE ;
COLOR RGB(0, 0, 0, 192, 192, 192)
MOVE WINDOW thermomete CENTER
ACTIVATE WINDOW thermomete NOSHOW
@ 0.5,3 SAY m.text FONT m.g_dlgface, m.g_dlgsize STYLE m.g_dlgstyle
@ 1.5,3 SAY m.prompt FONT m.g_dlgface, m.g_dlgsize STYLE m.g_dlgstyle
@ 0.000,0.000 TO 0.000,63.833 ;
COLOR RGB(255, 255, 255, 255, 255, 255)
@ 0.000,0.000 TO 5.615,0.000 ;
COLOR RGB(255, 255, 255, 255, 255, 255)
@ 0.385,0.667 TO 5.231,0.667 ;
COLOR RGB(128, 128, 128, 128, 128, 128)
@ 0.308,0.667 TO 0.308,63.167 ;
COLOR RGB(128, 128, 128, 128, 128, 128)
@ 0.385,63.000 TO 5.308,63.000 ;
COLOR RGB(255, 255, 255, 255, 255, 255)
@ 5.231,0.667 TO 5.231,63.167 ;
COLOR RGB(255, 255, 255, 255, 255, 255)
@ 5.538,0.000 TO 5.538,63.833 ;
COLOR RGB(128, 128, 128, 128, 128, 128)
@ 0.000,63.667 TO 5.615,63.667 ;
COLOR RGB(128, 128, 128, 128, 128, 128)
@ 3.000,3.333 TO 4.231,3.333 ;
COLOR RGB(128, 128, 128, 128, 128, 128)
@ 3.000,60.333 TO 4.308,60.333 ;
COLOR RGB(255, 255, 255, 255, 255, 255)
@ 3.000,3.333 TO 3.000,60.333 ;
COLOR RGB(128, 128, 128, 128, 128, 128)
@ 4.231,3.333 TO 4.231,60.500 ;
COLOR RGB(255, 255, 255, 255, 255, 255)
m.g_thermwidth = 56.269
CASE _MAC
DEFINE WINDOW thermomete ;
AT INT((SROW() - (( 5.62 * ;
FONTMETRIC(1, m.g_dlgface, m.g_dlgsize, m.g_dlgstyle )) / ;
FONTMETRIC(1, WFONT(1,""), WFONT( 2,""), WFONT(3,"")))) / 2), ;
INT((SCOL() - (( 63.83 * ;
FONTMETRIC(6, m.g_dlgface, m.g_dlgsize, m.g_dlgstyle )) / ;
FONTMETRIC(6, WFONT(1,""), WFONT( 2,""), WFONT(3,"")))) / 2) ;
SIZE 5.62,63.83 ;
FONT m.g_dlgface, m.g_dlgsize ;
STYLE m.g_dlgstyle ;
NOFLOAT ;
NOCLOSE ;
NONE ;
COLOR RGB(0, 0, 0, 192, 192, 192)
MOVE WINDOW thermomete CENTER
ACTIVATE WINDOW thermomete NOSHOW
IF ISCOLOR()
@ 0.000,0.000 TO 5.62,63.83 PATTERN 1;
COLOR RGB(192, 192, 192, 192, 192, 192)
@ 0.000,0.000 TO 0.000,63.83 ;
COLOR RGB(255, 255, 255, 255, 255, 255)
@ 0.000,0.000 TO 5.62,0.000 ;
COLOR RGB(255, 255, 255, 255, 255, 255)
@ 0.385,0.67 TO 5.23,0.67 ;
COLOR RGB(128, 128, 128, 128, 128, 128)
@ 0.31,0.67 TO 0.31,63.17 ;
COLOR RGB(128, 128, 128, 128, 128, 128)
@ 0.385,63.000 TO 5.31,63.000 ;
COLOR RGB(255, 255, 255, 255, 255, 255)
@ 5.23,0.67 TO 5.23,63.17 ;
COLOR RGB(255, 255, 255, 255, 255, 255)
@ 5.54,0.000 TO 5.54,63.83 ;
COLOR RGB(128, 128, 128, 128, 128, 128)
@ 0.000,63.67 TO 5.62,63.67 ;
COLOR RGB(128, 128, 128, 128, 128, 128)
@ 3.000,3.33 TO 4.23,3.33 ;
COLOR RGB(128, 128, 128, 128, 128, 128)
@ 3.000,60.33 TO 4.31,60.33 ;
COLOR RGB(255, 255, 255, 255, 255, 255)
@ 3.000,3.33 TO 3.000,60.33 ;
COLOR RGB(128, 128, 128, 128, 128, 128)
@ 4.23,3.33 TO 4.23,60.33 ;
COLOR RGB(255, 255, 255, 255, 255, 255)
ELSE
@ 0.000, 0.000 TO 5.62, 63.830 PEN 2
@ 0.230, 0.500 TO 5.39, 63.333 PEN 1
ENDIF
@ 0.5,3 SAY m.text FONT m.g_dlgface, m.g_dlgsize STYLE m.g_dlgstyle+"T" ;
COLOR RGB(0,0,0,192,192,192)
@ 1.5,3 SAY m.prompt FONT m.g_dlgface, m.g_dlgsize STYLE m.g_dlgstyle+"T" ;
COLOR RGB(0,0,0,192,192,192)
m.g_thermwidth = 56.27
IF !ISCOLOR()
@ 3.000,3.33 TO 4.23,m.g_thermwidth + 3.33
ENDIF
ENDCASE
SHOW WINDOW thermomete TOP
ELSE
m.prompt = SUBSTR(SYS(2014,m.g_outfile),1,48)+;
IIF(LEN(m.g_outfile)>48,"...","")
DEFINE WINDOW thermomete;
FROM INT((SROW()-6)/2), INT((SCOL()-57)/2) ;
TO INT((SROW()-6)/2) + 6, INT((SCOL()-57)/2) + 57;
DOUBLE COLOR SCHEME 5
ACTIVATE WINDOW thermomete NOSHOW
m.g_thermwidth = 50
@ 0,3 SAY m.text
@ 1,3 SAY UPPER(m.prompt)
@ 2,1 TO 4,m.g_thermwidth+4 &g_boxstrg
SHOW WINDOW thermomete TOP
ENDIF
RETURN
*
* UPDTHERM(<percent>) - Update thermometer.
*
*!*****************************************************************************
*!
*! Procedure: UPDTHERM
*!
*! Called by: BUILD (procedure in GENSCRN.PRG)
*! : DISPATCHBUILD (procedure in GENSCRN.PRG)
*! : BUILDCTRL (procedure in GENSCRN.PRG)
*! : EXTRACTPROCS (procedure in GENSCRN.PRG)
*! : BUILDFMT (procedure in GENSCRN.PRG)
*!
*!*****************************************************************************
PROCEDURE updtherm
PARAMETER m.percent
PRIVATE m.nblocks, m.percent
IF !WEXIST("thermomete")
DO acttherm WITH "Generating cross-tabulation ..."
ENDIF
ACTIVATE WINDOW thermomete
m.nblocks = (m.percent/100) * (m.g_thermwidth)
DO CASE
CASE _WINDOWS
@ 3.000,3.333 TO 4.231,m.nblocks + 3.333 ;
PATTERN 1 COLOR RGB(128, 128, 128, 128, 128, 128)
CASE _MAC
@ 3.000,3.33 TO 4.23,m.nblocks + 3.33 ;
PATTERN 1 COLOR RGB(0, 0, 128, 0, 0, 128)
OTHERWISE
@ 3,3 SAY REPLICATE("€",m.nblocks)
ENDCASE
RETURN
*
* DEACTTHERMO - Deactivate and Release thermometer window.
*
*!*****************************************************************************
*!
*! Procedure: DEACTTHERMO
*!
*!*****************************************************************************
PROCEDURE deactthermo
IF WEXIST("thermomete")
RELEASE WINDOW thermomete
ENDIF
RETURN
*!*****************************************************************************
*!
*! Procedure: PARTIALFNAME
*!
*!*****************************************************************************
FUNCTION partialfname
PARAMETER m.filname, m.fillen
* Return a filname no longer than m.fillen characters. Take some chars
* out of the middle if necessary. No matter what m.fillen is, this function
* always returns at least the file stem and extension.
PRIVATE m.bname, m.elipse
m.elipse = "..." + c_pathsep
m.bname = justfname(m.filname)
DO CASE
CASE LEN(m.filname) <= m.fillen
RETURN filname
CASE LEN(m.bname) + LEN(m.elipse) >= m.fillen
RETURN m.bname
OTHERWISE
m.remain = MAX(m.fillen - LEN(m.bname) - LEN(m.elipse), 0)
RETURN LEFT(justpath(m.filname),remain)+m.elipse+m.bname
ENDCASE
*!*****************************************************************************
*!
*! Procedure: removequotes
*!
*!*****************************************************************************
FUNCTION removequotes
PARAMETER m.fname
PRIVATE m.leftchar, m.rightchar
m.fname = ALLTRIM(m.fname)
m.leftchar = LEFT(m.fname,1)
m.rightchar = RIGHT(m.fname, 1)
IF m.leftchar = '"' AND m.rightchar = '"' ;
OR m.leftchar = "'" AND m.rightchar = "'" ;
OR m.leftchar = '[' AND m.rightchar = ']'
RETURN SUBSTR(m.fname, 2, LEN(m.fname) - 2)
ELSE
RETURN m.fname
ENDIF
*: EOF: GENXTAB.PRG